home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / tex / pil50kit.zip / CFILES / PILAPI.C < prev    next >
Encoding:
Text File  |  1992-04-09  |  57.1 KB  |  1,702 lines

  1. /* ----------------------------------------------------------------------------    */
  2. /*    Originators:                                                                */
  3. /*      Tom Arnold,    Quark, Inc.,    300 S. Jackson,     Denver,     CO 80209    */
  4. /*        Ron Perry,     Atex, Inc.,        165 Lexington Road,    Billerica,     MA 01821    */
  5. /* ----------------------------------------------------------------------------    */
  6. /*    The source code in this file is provided by Quark and Atex for use in the    */
  7. /*    development of a Publishing Interchange Language. The code provided herein    */
  8. /*    is non-proprietary, non-copyrighted, and is for use in the public domain.    */
  9. /*    The source code contained herein is provided "as is".                        */
  10. /* ----------------------------------------------------------------------------    */
  11. /*    QUARK AND ATEX DISCLAIM ALL WARRANTIES, EXPRESSED OR IMPLIED, WITH REGARD    */ 
  12. /*    TO THE ENCLOSED SOURCE CODE. QUARK AND ATEX DISCLAIM ANY IMPLIED WARRANTY,    */
  13. /*    INCLUDING, BUT NOT LIMITED TO ANY IMPLIED WARRANTY OF FITNESS FOR A            */
  14. /*    PARTICULAR PURPOSE OR MERCHANTABILITY.                                        */
  15. /* ----------------------------------------------------------------------------    */
  16.  
  17.  
  18. /*$ab ----------------------------- abstract ----------------------------------
  19.   pilapi.c       Contains interface routines for applications to access the pil
  20.                   parser and generator.
  21.                   
  22.                   NO MEMORY IS ALLOCATED OR FREED BY THE FUNCTIONS IN THIS MODULE!
  23.                   
  24.                   NO I/O (FILE OPENS, CLOSES, READS, OR WRITES, ERROR PRINTING)
  25.                   IS DONE DIRECTLY BY THE FUNCTIONS IN THIS MODULE.
  26.  
  27.                   ERRORS ARE COMMUNICATED TO THE APPLICATION BY RETURNING AN
  28.                   ERROR CODE AND SETTING A GLOBAL ERROR WORD WITH THAT ERROR CODE. 
  29.                   
  30.                   A function is provided to return the last PIL_ERROR set.
  31.                   
  32.                   The functions in this module manipulate a buffer that is 
  33.                   provided by the application. The parser/generator functions
  34.                   use memory from the buffer sequentially, and keep track of 
  35.                   what is used, by calling pil_alloc. However, there is no 
  36.                   corresponding pil_free to give back parts of the buffer. It
  37.                   is the application's responsibility to provide a buffer that
  38.                   is big enough for the structures being built. When the buffer
  39.                   is not large enough, PIL_OUT_OF_MEMORY will be returned by
  40.                   the function that requested memory. It is then up to the 
  41.                   application to provide a larger buffer, call pil_set_buffer,
  42.                   and retry. In the case of parsing, PIL_OUT_OF_MEMORY requires 
  43.                   restarting the parser at the beginning of the file.
  44.                   
  45.                   The application also provides pointers to functions to read
  46.                   and write characters.  The application must open the 
  47.                   necessary files for reading or writing the PIL, and set up the 
  48.                   getchar or putchar function pointers, and provide a buffer for
  49.                   the parser, before calling any function here that needs to read 
  50.                   or write! (This is be done with pil_pg_init.)
  51.                   
  52.                   The application can call the functions here to:
  53.                       read a pil file, putting pil structures into a buffer
  54.                       create pil structures in a buffer
  55.                       write pil structures from the buffer to a file
  56.                       write comments to a file
  57.                       
  58.                    The functions that read or create pil structs will put structures 
  59.                   at the next available location in the provided buffer, 
  60.                   and return an error code (PIL_ERROR). A pointer to the structure
  61.                   written, will be returned in a parameter passed to the function.
  62.  
  63.                   
  64.     Major functions for parsing and generating:
  65.     ------------------------------------------
  66.      
  67.         pil_pg_init                Initializes parser and generator
  68.         pil_get_component        Read the next thing from the file and put it in
  69.                                 the pil buffer.
  70.         pil_put_component        Write a pil_component to the open pil file
  71.         pil_create_component    Create a component of the requested type in the 
  72.                                 pil buffer at the next available location. This
  73.                                 allocates space in the buffer, clears it, and sets
  74.                                 up the structure with language-specific defaults. 
  75.  
  76.  
  77.     Utility functions for controlling parser/generator actions:
  78.     ----------------------------------------------------------
  79.     
  80.         pil_set_asa_list        Set up a list of application-specific-attributes
  81.                                 (asa) that the application wants the parser to 
  82.                                 return, ignoring all others.
  83.         pil_set_buffer            Set up the buffer that will be used for reads.
  84.         pil_set_cnt_bsize        Set the content data buffering size. This value is
  85.                                 initialized at pil_pg_init() time and can be modified
  86.                                 via this function.
  87.         pil_set_getc            Set get character function pointer
  88.         pil_set_putc            Set put character function pointer
  89.  
  90.  
  91.     Utility functions for status:
  92.     ----------------------------
  93.     
  94.         pil_get_mem_avail        Returns the number of bytes left in the pil buffer
  95.         pil_last_error            Returns the most recent PIL_ERROR
  96.         pil_get_version            Returns the language version and api version strings.
  97.         pil_get_line_num        Returns the line number where the parser encountered
  98.                                 an error.
  99.  
  100.  
  101.     Utility functions for creating PIL data structures:
  102.     --------------------------------------------------
  103.     
  104.         pil_alloc                   Allocates memory from the pil buffer
  105.         pil_create_asi                Create an application specific item
  106.         pil_create_asa                Create an application specific attribute
  107.         pil_create_pvalue            A pil_value for a pil_asa
  108.         pil_create_nametbleentry     A name table entry
  109.         pil_create_objid            an object id (for text flow or group)
  110.         pil_create_pathpt            A path point (for a pil_path)
  111.         pil_create_polypt            A polygon point
  112.         pil_create_layout_start        Create layout start component
  113.         pil_create_name_table        Create name table component
  114.         pil_create_canvas            Create canvas component
  115.         pil_create_object            Create object component
  116.         pil_create_text_flow        Create text flow component
  117.         pil_create_group            Create group component
  118.         pil_create_layout_end        Create layout end component
  119.         pil_create_content_start    Create content start component
  120.         pil_create_content_hdr        Create content header component
  121.         pil_create_content_data        Create content data component
  122.         pil_create_content_end        Create content end component
  123.  
  124.  
  125.     Utility functions for PIL file generation:
  126.     -----------------------------------------
  127.     
  128.         pil_put_comment            Write a comment into the pil file
  129.         pil_put_layout_start    Write a layout start component
  130.         pil_put_name_table        Write a name table component
  131.         pil_put_canvas            Write a canvas component
  132.         pil_put_object            Write a object component
  133.         pil_put_text_flow        Write a text flow component
  134.         pil_put_group            Write a group component
  135.         pil_put_layout_end        Write a layout end component
  136.         pil_put_content_start    Write a content start component
  137.         pil_put_content_hdr        Write a content header component
  138.         pil_put_content_data    Write a content data component
  139.         pil_put_content_end        Write a content end component
  140. ---------------------------------------------------------------------------- */
  141.  
  142.  
  143. /*$au ------------------------------ audits -----------------------------------
  144.     Author: Tom Arnold
  145.             Quark, Inc.
  146.             300 South Jackson
  147.             Denver, Colorado 80209
  148.             (303) 934-2211
  149.  
  150.     Ver     Date       Who  Etc
  151.     v01.02  24-apr-91  tla    Upgraded for PIL 5.0
  152.     v01.01  03-apr-91  tla    Fixed 2 bugs in pil_set_buffer, one in pil_alloc,
  153.         that could allow pointers to improper address boundaries, and allow
  154.         the buf to be overrun by several bytes. Changed pil_api_ver to b01.01
  155.     v01.00  12-feb-91  tla    Initial version
  156. ---------------------------------------------------------------------------- */
  157.  
  158.  
  159. /*$ep --------------------------- header files ---------------------------- */
  160.  
  161. #ifdef        THINK_DA    /* Support for THINK C Desk Accessory Architecture     */
  162. #include     <SANE.h>    /* Pickup num2str                                     */
  163. #else                    /* else                                             */
  164. #include    <stdlib.h>    /* Use stdlib for atof                                */
  165. #endif                    /* end of THINK_DA                                     */
  166. #include    "pildefs.h"    /* Pick up PIL data structures and defines            */
  167.  
  168.  
  169.  
  170.  
  171. /*$ed ------------------------ public global data -------------------------- */
  172.  
  173. #ifdef PIL_ANSI_PROTOTYPES
  174. extern    PIL_VOID (FPTRTYPE *pil_putchar)(PIL_UINT8);/* Appl PutChar function */
  175. extern    int (FPTRTYPE *pil_getchar)(PIL_VOID);         /* Appl GetChar function */
  176. #else
  177. extern    PIL_VOID (FPTRTYPE *pil_putchar)();            /* Appl PutChar function */
  178. extern    int (FPTRTYPE *pil_getchar)();                 /* Appl GetChar function */
  179. #endif
  180. extern    char PTRPTR    pil_asa_list;        /* appl. specific attribute names    */
  181. extern    PIL_INT32 pil_asa_count;        /* <0 = All, 0 = None ,>0 = use list */
  182. extern    PIL_UINT32 pil_cnt_buf_size;    /* Buffering size for content data   */
  183. extern    char PTRTYPE *pil_kws[];        /* Keyword pointer array             */
  184.  
  185.  
  186. /*$ld --------------------------- static  data ----------------------------- */
  187.  
  188. /*    The PIL language version that this API interfaces to. The generator will */
  189. /*    produce the version given below. The parser is able to parse any version */
  190. /*    with the same major revision number (the part before the ".") and a minor */
  191. /*    version number that is equal to or less than the minor version number of */
  192. /*    pil_version. (E.g., if pil_version is "04.04" then the parser can also     */
  193. /*    understand version 4.01, 4.02, and 4.03) */
  194.  
  195. static char pil_version[6]={ '0', '5', '.', '0', '0', '\0' };
  196.  
  197. /*    And a version number for the API itself. This number also has a major and */
  198. /*    a minor part. The major rev number changes when data structures or */
  199. /*    function prototypes for the api change, or when functions are added or */
  200. /*    removed from the api. The minor rev number changes with any code change to */
  201. /*    this file, e.g., bug fixes, etc. */
  202.  
  203. static char    pil_api_ver[6]={ '0','2','.','0','0','\0' };
  204.  
  205. /* Last error code and PIL buffer accounting variables */
  206.  
  207. static PIL_ERROR    pil_error_val;        /* error word                       */
  208. static char PTRTYPE *pil_bufstart;        /* beginning of buffer              */
  209. static char PTRTYPE *pil_bufferptr;        /* next free space in the buffer    */
  210. static PIL_UINT32    pil_bufremaining;    /* space left in buffer (bytes)     */
  211.  
  212. /*$co ---------------------------- code start ----------------------------- */
  213.         
  214.  
  215. /* ------------------------------------------------------------------------    */
  216. /*        M A I N  S T R E A M  F U N C T I O N S                                */
  217. /* ------------------------------------------------------------------------    */
  218. /*            pil_pg_init                (in this file)                            */
  219. /*            pil_create_component    (in this file)                            */
  220. /*            pil_get_component        (in pilparse.c)                            */
  221. /*            pil_put_component        (in pilgen.c)                            */
  222. /* ------------------------------------------------------------------------    */
  223.  
  224.  
  225. /*-----------------------------------------------------------------------*\
  226.   pil_pg_init
  227.  
  228.     Tell the parser and generator to initialize any data structures needed.
  229.     In addition, establish:
  230.         o parser/generator buffer pointer and size
  231.         o getchar function pointer
  232.         o putchar function pointer
  233.         o content data buffering size
  234.         o which application specific items are to be reported to the caller
  235.         
  236.     ALL ARGUMENTS ARE REQUIRED. If only parsing is intended, pass NULL for
  237.     putchar_p. If only generating is intended, pass NULL for getchar_p.
  238.  
  239.     The getchar function provided must:
  240.         o Take no arguments (which means it must know what file to read)    
  241.         o Return an int, with the ASCII character in the low-order 8 bits
  242.         o Return a -1 for end of file
  243.  
  244.     The parser assumes that the application will have opened the
  245.     required file for the getchar function, and has set up whatever 
  246.     data (e.g., file pointer, read buffer, etc) the function requires 
  247.     to read the PIL file, BEFORE calling any routines that call the 
  248.     getchar function. These include: pil_get_component.
  249.  
  250.     The putchar function provided must:    
  251.         o Take one argument, a character        
  252.         o Returns nothing
  253.     
  254.     The generator assumes that the application will have opened the
  255.     required file for the putchar function, BEFORE calling any routines 
  256.     that call the putchar function. These include: pil_put_*.
  257.  
  258.  
  259.     Entry:    bufptr        pointer to buffer for use of the parser/generator
  260.             size        size of buffer in bytes
  261.             getcharp    pointer to getchar function
  262.             putcharp    pointer to putchar function
  263.             cntbufsize    content data buffering size
  264.             asi_count    <0 == All, 0 == None , >0 means use asi_names
  265.             asi_names    application specific item names
  266.  
  267.     Exit:    error code (from pildefs.h)
  268. \*-----------------------------------------------------------------------*/
  269.  
  270. PIL_ERROR pil_pg_init (bufptr, size, getchar_p, putchar_p, cntbufsize,
  271. asi_count, asi_name)
  272.  
  273. char PTRTYPE     *bufptr;
  274. PIL_UINT32        size;
  275. #ifdef PIL_ANSI_PROTOTYPES
  276. int             (FPTRTYPE *getchar_p)(PIL_VOID);
  277. PIL_VOID          (FPTRTYPE *putchar_p)(PIL_UINT8);
  278. #else
  279. int             (FPTRTYPE *getchar_p)();
  280. PIL_VOID          (FPTRTYPE *putchar_p)();
  281. #endif
  282. PIL_UINT32         cntbufsize;
  283. PIL_INT32        asi_count;
  284. char PTRPTR        asi_name;
  285. {
  286.     if (pil_set_buffer (bufptr, size) != PIL_OK) return (pil_last_error());
  287.     if (getchar_p == NULL && putchar_p == NULL) return (pil_set_error(PIL_NO_RW_FUNCS));
  288.     pil_getchar = getchar_p;
  289.     pil_putchar = putchar_p;
  290.  
  291.  
  292.     if (pil_set_cnt_bsize (cntbufsize) != PIL_OK) return (pil_last_error());
  293.     if (pil_set_asa_list (asi_count, asi_name) != PIL_OK) return (pil_last_error());
  294.     pil_init_keywords ();
  295.     pil_init_parser ();
  296.     return (PIL_OK);
  297. }
  298.  
  299.  
  300. /*-----------------------------------------------------------------------*\
  301.   pil_create_component
  302.  
  303.     Creates a pil "component" of the requested type in the pil buffer.
  304.     A pil component is defined in pilstruct.h.
  305.     The component is put in the buffer at the next available location,
  306.     and is initialized to the defaults as defined in the language spec.    
  307.  
  308.     Entry:    Pointer to a pil_component *, and type of requested component.
  309.  
  310.     Exit:    *cptrptr points to new component. Error code is returned.
  311. \*-----------------------------------------------------------------------*/
  312.  
  313. PIL_ERROR pil_create_component (cptrptr,type)
  314. FAST pil_component PTRPTR cptrptr;
  315. PIL_COMP_TYPE type;
  316. {
  317.     if (type == PIL_LAYOUT_START_C)
  318.         return (pil_create_layout_start((pil_layout_start PTRPTR)cptrptr));
  319.     if (type == PIL_NAME_TABLE_C)
  320.         return (pil_create_name_table((pil_name_table PTRPTR)cptrptr));
  321.     if (type == PIL_CANVAS_C)
  322.         return (pil_create_canvas((pil_canvas PTRPTR)cptrptr));
  323.     if (type == PIL_OBJECT_C)
  324.         return (pil_create_object((pil_object PTRPTR)cptrptr));
  325.     if (type == PIL_TEXT_FLOW_C)
  326.         return (pil_create_text_flow((pil_text_flow PTRPTR)cptrptr));
  327.     if (type == PIL_GROUP_C)
  328.         return (pil_create_group((pil_group PTRPTR)cptrptr));
  329.     if (type == PIL_LAYOUT_END_C)
  330.         return (pil_create_layout_end((pil_layout_end PTRPTR)cptrptr));
  331.     if (type == PIL_CONTENT_START_C)
  332.         return (pil_create_content_start((pil_content_start PTRPTR)cptrptr));
  333.     if (type == PIL_CONTENT_HDR_C)
  334.         return (pil_create_content_hdr((pil_content_hdr PTRPTR)cptrptr));
  335.     if (type == PIL_CONTENT_DATA_C)
  336.         return (pil_create_content_data((pil_content_data PTRPTR)cptrptr));
  337.     if (type == PIL_CONTENT_END_C)
  338.         return (pil_create_content_end((pil_content_end PTRPTR)cptrptr));
  339.     return (pil_set_error(PIL_BAD_CMPNT_TYPE));
  340. }
  341.  
  342.  
  343. /* ------------------------------------------------------------------------    */
  344. /*        S E T  F U N C T I O N S                                            */
  345. /* ------------------------------------------------------------------------    */
  346. /*            pil_set_buffer                                                    */
  347. /*            pil_set_cnt_bsize                                                */
  348. /*            pil_set_asa_list                                                */
  349. /*            pil_set_getc                                                    */
  350. /*            pil_set_putc                                                    */
  351. /* ------------------------------------------------------------------------    */
  352.  
  353.  
  354. /*-----------------------------------------------------------------------*\
  355.   pil_set_buffer
  356.  
  357.     Give the parser/generator a place to put/look for pil
  358.     structures. The buffer passed is used by the parser for all
  359.     structures it creates, so the parser itself does not need to
  360.     do any memory allocation or deallocation. 
  361.     
  362.     pil_set_buffer is called by pil_pg_init. It may also be called
  363.     directly to reset the buffer pointer, for example, to reuse the
  364.     same buffer on subsequent calls to pil_get_component or
  365.     pil_create_component
  366.  
  367.     NOTE:    Some cpus require that certain sized structures must
  368.             be aligned to a particular address boundaries. The most
  369.             common form of this restriction is that integers or long 
  370.             integers must not start on odd numbered addresses. To honor
  371.             this requirement, pil_set_buffer make sure that the buffer
  372.             address is a multiple of the constant PIL_MEM_ALIGN_SIZE, 
  373.             which may be defined in pildefs.h
  374.     
  375.     Entry: Pointer to buffer, size of buffer in bytes.
  376.  
  377.     Exit:  PIL_NO_BUFPTR, if a NULL pointer or a size of zero is passed.
  378.            Else, PIL_OK. Initializes private data needed to maintain 
  379.            buffer.
  380. \*-----------------------------------------------------------------------*/
  381.  
  382. PIL_ERROR pil_set_buffer (bufptr, size)
  383. char PTRTYPE *bufptr;
  384. PIL_UINT32    size;
  385. {
  386.     PIL_UINT32 align;
  387.     if (bufptr == NULL || size == 0) return (pil_set_error(PIL_NO_BUFPTR));
  388.  
  389. #ifdef PIL_MEM_ALIGN_SIZE
  390.     /* force alignment to the required address boundary */
  391.     align = ((PIL_ADDR_T) bufptr % PIL_MEM_ALIGN_SIZE);
  392.     if (align != 0)
  393.     {
  394.         bufptr += (PIL_MEM_ALIGN_SIZE - align);
  395.         size -= (PIL_MEM_ALIGN_SIZE - align);
  396.     }
  397. #endif
  398.     
  399.     pil_bufstart = pil_bufferptr = bufptr;
  400.     pil_bufremaining = size;    
  401.     return (PIL_OK);
  402. }
  403.  
  404.  
  405. /*-----------------------------------------------------------------------*\
  406.   pil_set_cnt_bsize
  407.  
  408.     Sets the PIL content buffering size and returns PIL_OK if the given
  409.     argument is valid. The buffering size must not be zero and must not
  410.     be greater than the amount of memory remaining in the pil buffer.
  411.  
  412.     Entry: PIL_UINT32
  413.  
  414.     Exit: PIL_OK or PIL_BAD_CBUF_SIZE
  415. \*-----------------------------------------------------------------------*/
  416.  
  417. PIL_ERROR pil_set_cnt_bsize (cnt_bsize)
  418. PIL_UINT32 cnt_bsize;
  419. {
  420.     if (cnt_bsize == 0) return (pil_set_error(PIL_BAD_CBUF_SIZE));
  421.     if (cnt_bsize > pil_bufremaining) return (pil_set_error(PIL_BAD_CBUF_SIZE));
  422.     pil_cnt_buf_size = cnt_bsize;
  423.     return (PIL_OK);
  424. }
  425.  
  426.  
  427. /*-----------------------------------------------------------------------*\
  428.   pil_set_asa_list
  429.  
  430.     Set up a list of application-specific-attributes that the application 
  431.     wants the parser to return, ignoring all others.
  432.     NOTE: The list of attribute names is NOT copied. A pointer to it is 
  433.     maintained for the parser. Therefore the application must not destroy,
  434.     move, or change the list
  435.  
  436.     Entry:    Count of number of attributes to accept.
  437.             Count = 0    don't return any application specific attributes
  438.             Count < 0    return ALL application specific attributes
  439.             Count > 0    return application specific attributes named in list
  440.             Also, pointer to array of pointers to string representing the 
  441.             names of the attributes to accept, if Count > 0.
  442.  
  443.     Exit:    PIL_NO_ASALISTPTR, if count > 0 and list ptr is null,
  444.             else PIL_OK
  445. \*-----------------------------------------------------------------------*/
  446.  
  447. PIL_ERROR    pil_set_asa_list (count, names)
  448. PIL_INT32    count;
  449. char PTRPTR names;            /* if count>0, names[] is char *names[count] */
  450. {
  451.     pil_asa_count = count;
  452.     if (count > 0) 
  453.     {
  454.         if (names == NULL) return (pil_set_error(PIL_NO_ASALISTPTR));
  455.         pil_asa_list = names;
  456.     }
  457.     else 
  458.     {
  459.         pil_asa_list = NULL;
  460.     }
  461.     return (PIL_OK);
  462. }
  463.     
  464.  
  465. /*-----------------------------------------------------------------------*\
  466.   pil_set_getc
  467.  
  468.     Set the PIL get character function pointer
  469.  
  470.     Entry:    function pointer to your getc routine
  471.     
  472.     Exit:    PIL_NO_R_FUNC or PIL_OK
  473. \*-----------------------------------------------------------------------*/
  474.  
  475. PIL_ERROR pil_set_getc (getchar_p)
  476. #ifdef        PIL_ANSI_PROTOTYPES
  477. int (FPTRTYPE *getchar_p)(PIL_VOID);
  478. #else
  479. int (FPTRTYPE *getchar_p)();
  480. #endif
  481. {
  482.     if (getchar_p == NULL) return (pil_set_error(PIL_NO_R_FUNC));
  483.     pil_getchar = getchar_p;
  484.     return (PIL_OK);
  485. }
  486.     
  487.  
  488. /*-----------------------------------------------------------------------*\
  489.   pil_set_putc
  490.  
  491.     Set the PIL put character function pointer
  492.  
  493.     Entry:    function pointer to your putc routine. putc routine must take
  494.             a PIL_UINT8 as input, and return nothing.
  495.     
  496.     Exit:    PIL_NO_W_FUNC or PIL_OK
  497. \*-----------------------------------------------------------------------*/
  498.  
  499. PIL_ERROR pil_set_putc (putchar_p)
  500. #ifdef        PIL_ANSI_PROTOTYPES
  501. PIL_VOID (FPTRTYPE *putchar_p)(PIL_UINT8);
  502. #else
  503. PIL_VOID (FPTRTYPE *putchar_p)();
  504. #endif
  505. {
  506.     if (putchar_p == NULL) return (pil_set_error(PIL_NO_W_FUNC));
  507.     pil_putchar = putchar_p;
  508.     return (PIL_OK);
  509. }
  510.  
  511.  
  512. /* ------------------------------------------------------------------------    */
  513. /*        S T A T U S  F U N C T I O N S                                        */
  514. /* ------------------------------------------------------------------------    */
  515. /*            pil_get_version                                                    */
  516. /*            pil_get_mem_avail                                                */
  517. /*            pil_last_error                                                    */
  518. /*            pil_get_line_num (in pilparse.c)                                */
  519. /* ------------------------------------------------------------------------    */
  520.  
  521.  
  522. /*-----------------------------------------------------------------------*\
  523.   pil_get_version
  524.  
  525.     Get the version strings for the PIL language and the PIL API itself.
  526.  
  527.     Entry:    char **language - pointer to pointer for language version str.
  528.              char **api - pointer to pointer for api version string
  529.  
  530.     Exit:    returns PIL_OK, 
  531.             returns pointer to language and api version strings.
  532. \*-----------------------------------------------------------------------*/
  533.  
  534. PIL_ERROR pil_get_version (language, api)
  535. char    PTRPTR    language;
  536. char    PTRPTR    api;
  537. {
  538.     *language = pil_version;
  539.     *api = pil_api_ver;
  540.     return (PIL_OK);
  541. }
  542.  
  543.  
  544. /*-----------------------------------------------------------------------*\
  545.   pil_get_mem_avail
  546.  
  547.     Returns the number of bytes available in the pil buffer.
  548.  
  549.     Entry: none
  550.  
  551.     Exit:  number of bytes unused at the end of the pil buffer
  552. \*-----------------------------------------------------------------------*/
  553.  
  554. PIL_ERROR pil_get_mem_avail (count)
  555. PIL_UINT32 PTRTYPE *count;
  556. {
  557.     if (pil_bufferptr == NULL) 
  558.     {
  559.         *count = 0;
  560.         return (pil_set_error(PIL_NO_BUFPTR));
  561.     }
  562.     else 
  563.     {
  564.         *count = pil_bufremaining;
  565.         return (PIL_OK);
  566.     }
  567. }
  568.  
  569.  
  570. /*-----------------------------------------------------------------------*\
  571.   pil_last_error
  572.  
  573.     Returns the last PIL_ERROR recorded.
  574.  
  575.     Entry: none
  576.  
  577.     Exit:  value pil error word
  578. \*-----------------------------------------------------------------------*/
  579.  
  580. PIL_ERROR pil_last_error ()
  581. {
  582.     return (pil_error_val);
  583. }
  584.  
  585.  
  586. /* ------------------------------------------------------------------------    */
  587. /*        C R E A T I O N  F U N C T I O N S                                    */
  588. /* ------------------------------------------------------------------------    */
  589. /*            pil_alloc                                                        */
  590. /*            pil_create_asa                                                    */
  591. /*            pil_create_asi                                                    */
  592. /*            pil_create_nametbleentry                                         */
  593. /*            pil_create_objid                                                */
  594. /*            pil_create_pathpt                                                */
  595. /*            pil_create_polypt                                                */
  596. /*            pil_create_pvalue                                                */
  597. /*            pil_create_layout_start                                            */
  598. /*            pil_create_name_table                                            */
  599. /*            pil_create_canvas                                                */
  600. /*            pil_create_object                                                */
  601. /*            pil_create_text_flow                                            */
  602. /*            pil_create_group                                                */
  603. /*            pil_create_layout_end                                            */
  604. /*            pil_create_content_start                                        */
  605. /*            pil_create_content_hdr                                            */
  606. /*            pil_create_content_data                                            */
  607. /*            pil_create_content_end                                            */
  608. /* ------------------------------------------------------------------------    */
  609.  
  610.  
  611. /*-----------------------------------------------------------------------*\
  612.   pil_alloc
  613.  
  614.     Low-level routine that "allocates" memory chunks from the pil_buffer.
  615.     Checks to see if the requested amount of memory is available in the
  616.     buffer, and returns a pointer to the next available memory if it is.
  617.     NOTE:    pil_set_buffer MUST be called before pil_alloc, or any 
  618.             routine that calls pil_alloc. These include:
  619.                 pil_append_string
  620.                 pil_get_component
  621.                 pil_create_component
  622.             If this is not done, the buffer pointer will be null and
  623.             pil_alloc will return PIL_NO_BUFPTR.
  624.     NOTE:    pil_alloc just uses memory sequentially from the global
  625.             buffer set up by pil_set_buffer. It keeps track of what is 
  626.             left.  
  627.             Obviously, the application has a pointer to the buffer
  628.             when it calls calls pil_set_buffer.
  629.             HOWEVER, if the application wants to WRITE anything in that
  630.             buffer, it should call pil_alloc to find the next place to 
  631.             write. This will keep the application and parser from
  632.             stepping on each other's data.
  633.     NOTE:    Some cpus require that certain sized structures must
  634.             be aligned to a particular address boundaries. The most
  635.             common form of this restriction is that integers or long 
  636.             integers must not start on odd numbered addresses. To honor
  637.             this requirement, pil_alloc will only return pointers whose
  638.             address is a multiple of the constant PIL_MEM_ALIGN_SIZE, 
  639.             which may be defined in pildefs.h
  640.     NOTE:     there is no pil_free.
  641.  
  642.     Entry:    requested memory size
  643.             pointer to pointer, which will be initialize to point to the 
  644.                 block allocated.
  645.  
  646.     Exit:    If o.k., PIL_OK and *memptrptr set to address of the
  647.                 requested block
  648.             Else some other error code, and *memptrptr == NULL,
  649. \*-----------------------------------------------------------------------*/
  650.  
  651. PIL_ERROR    pil_alloc(length, memptrptr)
  652. PIL_UINT32    length;
  653. PIL_VOID    PTRPTR memptrptr;
  654. {    
  655. #ifdef PIL_MEM_ALIGN_SIZE
  656.     /* force alignment to a pointer-sized boundary */
  657.     length += length % PIL_MEM_ALIGN_SIZE;
  658.     length += (PIL_MEM_ALIGN_SIZE - (length % PIL_MEM_ALIGN_SIZE));
  659. #endif
  660.  
  661.  
  662.     if (pil_bufremaining < length) 
  663.     {
  664.         *memptrptr = NULL;
  665.         return (pil_set_error(PIL_OUT_OF_MEMORY));
  666.     }
  667.     
  668.     
  669.     /* Make sure that the buffer pointer was initialized */
  670.     if ((*memptrptr = (PIL_VOID PTRTYPE *) pil_bufferptr) == NULL) 
  671.     {
  672.         return (pil_set_error(PIL_NO_BUFPTR));
  673.     }
  674.     pil_bufremaining -= length;
  675.     pil_bufferptr += length;
  676.     return (PIL_OK);
  677. }
  678.  
  679.  
  680. /*-----------------------------------------------------------------------*\
  681.   pil_create_canvas
  682.  
  683.     Subroutine for pil_create_component.
  684.     Creates a pil_canvas in the pil buffer.
  685.     The pil_canvas is put in the buffer at the next available location.
  686.  
  687.     Entry:    Pointer to a pil_canvas *
  688.  
  689.     Exit:    *cptrptr points to new component. Error code is returned.
  690. \*-----------------------------------------------------------------------*/
  691.  
  692. PIL_ERROR pil_create_canvas (cptrptr)
  693. pil_canvas PTRPTR cptrptr;
  694. {
  695.     if (pil_alloc ((PIL_UINT32) sizeof(pil_canvas), 
  696.         (PIL_VOID PTRPTR) cptrptr) != PIL_OK) 
  697.         return (pil_last_error());
  698.  
  699.  
  700.     pil_clear ((char PTRTYPE *) *cptrptr, (PIL_UINT32) sizeof(pil_canvas));
  701.     (*cptrptr)->type = PIL_CANVAS_C;
  702.     (*cptrptr)->clipshape.type = PIL_DFT_CNV_CLIPPER;
  703.     return (PIL_OK);
  704. }
  705.  
  706.  
  707. /*-----------------------------------------------------------------------*\
  708.   pil_create_name_table
  709.  
  710.     Subroutine for pil_create_component.
  711.     Creates a pil_name_table in the pil buffer.
  712.     The pil_name_table is put in the buffer at the next available location,
  713.     and is initialized to the defaults as defined in the language spec.    
  714.  
  715.     Entry:    Pointer to a pil_name_table *
  716.  
  717.     Exit:    *nptrptr points to new pil_name_table. Error code is returned.
  718. \*-----------------------------------------------------------------------*/
  719.  
  720. PIL_ERROR pil_create_name_table (nptrptr)
  721. pil_name_table PTRPTR nptrptr;
  722. {
  723.     if (pil_alloc ((PIL_UINT32) sizeof(pil_name_table), 
  724.         (PIL_VOID PTRPTR) nptrptr) != PIL_OK) 
  725.         return (pil_last_error());
  726.  
  727.  
  728.     pil_clear ((char PTRTYPE *) *nptrptr, (PIL_UINT32) sizeof(pil_name_table));
  729.     (*nptrptr)->type = PIL_NAME_TABLE_C;
  730.     return (PIL_OK);
  731. }
  732.  
  733.  
  734. /*-----------------------------------------------------------------------*\
  735.   pil_create_nametblentry
  736.  
  737.     Creates a pil_name_table_entry in the pil buffer.
  738.     The pil_name_table is put in the buffer at the next available location,
  739.     and is initialized to the values passed.    
  740.  
  741.     Entry:    Pointer to a pil_name_table *
  742.             char *     name of entry
  743.             PIL_INT16    content type of entry
  744.             PIL_INT16    domain type
  745.             char *    content string
  746.             char *    value of entry
  747.  
  748.     Exit:    Error code is returned.
  749.             nptrptr points to new pil_name_table_entry
  750. \*-----------------------------------------------------------------------*/
  751.  
  752. PIL_ERROR pil_create_nametbleentry (aptrptr, name, tcode, tstring,
  753. dcode, dstring, vcode, vstring)
  754.  
  755. pil_name_table_entry PTRPTR aptrptr;    /* Destination for creation         */
  756. char PTRTYPE     *name;                    /* entry name                         */
  757. PIL_NT_TYPE        tcode;                    /* content type code                 */
  758. char PTRTYPE     *tstring;                /* content type string                 */
  759. PIL_NT_DMN        dcode;                    /* domain type code                 */
  760. char PTRTYPE     *dstring;                /* domain name string                 */
  761. PIL_NT_VAL        vcode;                    /* value type code                     */
  762. char PTRTYPE     *vstring;                /* value name string                 */
  763. {
  764.     FAST pil_name_table_entry PTRTYPE *nte;
  765.     if (pil_alloc((PIL_UINT32)sizeof(pil_name_table_entry),
  766.         (PIL_VOID PTRPTR)aptrptr) != PIL_OK) 
  767.         return (pil_last_error());
  768.  
  769.  
  770.     nte = *aptrptr;
  771.     nte->next = NULL;
  772.     if (pil_append_string(name,&nte->name) != PIL_OK) 
  773.     return (pil_last_error());
  774.  
  775.  
  776.     nte->content_type_code = tcode;
  777.     if (pil_append_string(tstring,&nte->content_type_string) != PIL_OK)
  778.     return (pil_last_error());
  779.  
  780.  
  781.     nte->domain_type_code = dcode;
  782.     if (pil_append_string(dstring,&nte->domain_type_string) != PIL_OK)
  783.     return (pil_last_error());
  784.  
  785.  
  786.     nte->value_type_code = vcode;
  787.     if (pil_append_string(vstring,&nte->value_type_string) != PIL_OK)
  788.     return (pil_last_error());
  789.     return (PIL_OK);
  790. }
  791.  
  792.  
  793. /*-----------------------------------------------------------------------*\
  794.   pil_create_asi
  795.  
  796.     Creates a pil_asi in the pil buffer at the next 
  797.     available location. It is given a name. The pil_asa
  798.     can be created by calling pil_create_asa.
  799.  
  800.     Entry:    Pointer to a pil_asi *
  801.             pointer to name of the pil_asi
  802.  
  803.     Exit:    *aptrptr points to new pil_asi. 
  804.             Error code is returned.
  805. \*-----------------------------------------------------------------------*/
  806.  
  807. PIL_ERROR pil_create_asi (aptrptr, name)
  808. pil_asi PTRPTR aptrptr;
  809. char PTRTYPE *name;
  810. {
  811.     FAST pil_asi PTRTYPE *asi;
  812.     if (pil_alloc((PIL_UINT32)sizeof(pil_asi),
  813.         (PIL_VOID PTRPTR)aptrptr) != PIL_OK) 
  814.         return (pil_last_error());
  815.  
  816.  
  817.     asi = *aptrptr;
  818.     asi->next = NULL;
  819.     asi->asa = NULL;
  820.     if (pil_append_string(name, &asi->asi_name) != PIL_OK) 
  821.         return (pil_last_error());
  822.     return (PIL_OK);
  823. }
  824.  
  825.  
  826. /*-----------------------------------------------------------------------*\
  827.   pil_create_asa
  828.  
  829.     Creates a pil_asa in the pil buffer.
  830.     The pil_asa is put in the buffer at the next 
  831.     available location. It is given a name a list of values as passed
  832.     to this function.
  833.  
  834.     Entry:    Pointer to a pil_asa *
  835.             PIL_UINT32            number of PIL_VALUES for this attribute
  836.             PIL_ASA_VAL_TYPE    code specifying data type for each pil_value
  837.             char *                name of the pil_asa
  838.             char *                pointer to an array of values of the 
  839.                                 specified type
  840.  
  841.     Exit:    *aptrptr points to new pil_asa. 
  842.             Error code is returned.
  843. \*-----------------------------------------------------------------------*/
  844.  
  845. PIL_ERROR pil_create_asa (aptrptr, name, count, type, data)
  846. pil_asa PTRPTR         aptrptr;
  847. char PTRTYPE         *name;
  848. PIL_UINT32            count;
  849. PIL_ASA_VAL_TYPE    type;
  850. char PTRTYPE         *data;
  851. {
  852.     pil_value    PTRPTR pv;
  853.     PIL_UINT32    itemsize;
  854.  
  855.     
  856.     if (pil_alloc ((PIL_UINT32) sizeof(pil_asa), 
  857.         (PIL_VOID PTRPTR) aptrptr) != PIL_OK) 
  858.         return (pil_last_error());
  859.         
  860.         
  861.     /* set the name, data type, and count of values for the attribute */
  862.     (*aptrptr)->next = NULL;
  863.     (*aptrptr)->count = count;
  864.     (*aptrptr)->type = type;
  865.     if (pil_append_string(name, &(*aptrptr)->attr_name) != PIL_OK)
  866.         return (pil_last_error());
  867.         
  868.         
  869.     if (count == 0)                    /* no values, clear pointer */
  870.     {
  871.         (*aptrptr)->value = NULL;
  872.     }
  873.     else                             /* create the list of values */
  874.     {
  875.         /*  data is declared as a char * so that pointer addition can be done     */
  876.         /*    in bytes. So now we get the size of the actual data items, and we     */
  877.         /*    add that as we advance through the array.                             */
  878.         
  879.         switch (type) 
  880.         {
  881.             case PIL_DOUBLE_CODE:
  882.             case PIL_DOUBLE_LIST_CODE:
  883.                 itemsize = (PIL_UINT32) sizeof(PIL_DOUBLE);
  884.                 break;
  885.                 
  886.             case PIL_INT16_CODE:
  887.             case PIL_INT16_LIST_CODE:
  888.             case PIL_UINT16_CODE:
  889.             case PIL_UINT16_LIST_CODE:
  890.                 itemsize = (PIL_UINT32) sizeof(PIL_INT16);
  891.                 break;
  892.                 
  893.             case PIL_INT32_CODE:
  894.             case PIL_INT32_LIST_CODE:
  895.             case PIL_UINT32_CODE:
  896.             case PIL_UINT32_LIST_CODE:
  897.                 itemsize = (PIL_UINT32) sizeof(PIL_INT32);
  898.                 break;
  899.                 
  900.             case PIL_STRING_CODE:
  901.             case PIL_STRING_LIST_CODE:
  902.                 itemsize = (PIL_UINT32) sizeof(char PTRTYPE *);
  903.                 break;
  904.                 
  905.             case PIL_INT8_CODE:
  906.             case PIL_INT8_LIST_CODE:
  907.             case PIL_UINT8_CODE:
  908.             case PIL_UINT8_LIST_CODE:
  909.                 itemsize = (PIL_UINT32) sizeof(PIL_INT8);
  910.                 break;
  911.                 
  912.             default:
  913.                 return (pil_set_error(PIL_BAD_VALUE_TYPE));
  914.         }
  915.         for (pv = &(*aptrptr)->value; count != 0; count--) 
  916.         {
  917.             if (pil_create_pvalue(pv,type,data) != PIL_OK) return (pil_last_error());
  918.             data += itemsize;
  919.             pv = &(*pv)->next;
  920.         }
  921.     }
  922.     return (PIL_OK);
  923. }
  924.  
  925.  
  926. /*-----------------------------------------------------------------------*\
  927.   pil_create_pvalue
  928.  
  929.     Creates a pil_value in the pil buffer at the next available location.
  930.  
  931.     Entry:    Pointer to a pil_value *
  932.             PIL_ASA_VAL_TYPE    code specifying data type for each pil_value
  933.             char *                pointer to value for the pil_value
  934.  
  935.     Exit:    *aptrptr points to new pil_value. 
  936.             Error code is returned.
  937. \*-----------------------------------------------------------------------*/
  938.  
  939. PIL_ERROR pil_create_pvalue (aptrptr, type, data)
  940. pil_value PTRPTR     aptrptr;
  941. PIL_ASA_VAL_TYPE    type;
  942. FAST char PTRTYPE     *data;
  943. {
  944.     FAST pil_value PTRTYPE *pv;
  945.  
  946.  
  947.     if (pil_alloc ((PIL_UINT32) sizeof(pil_value), 
  948.         (PIL_VOID PTRPTR) aptrptr) != PIL_OK) 
  949.         return (pil_last_error());
  950.         
  951.         
  952.     pv = *aptrptr;
  953.     pil_clear ((char PTRTYPE *) pv, (PIL_UINT32) sizeof (pil_value));
  954.     
  955.     
  956.     switch (type) 
  957.     {
  958.         case PIL_INT8_CODE:
  959.         case PIL_INT8_LIST_CODE:
  960.             pv->data.int8 = *(PIL_INT8 PTRTYPE *) data;
  961.             break;
  962.             
  963.         case PIL_INT16_CODE:
  964.         case PIL_INT16_LIST_CODE:
  965.             pv->data.int16 = *(PIL_INT16 PTRTYPE *) data;
  966.             break;
  967.             
  968.         case PIL_INT32_CODE:
  969.         case PIL_INT32_LIST_CODE:
  970.             pv->data.int32 = *(PIL_INT32 PTRTYPE *) data;
  971.             break;
  972.             
  973.         case PIL_UINT8_CODE:
  974.         case PIL_UINT8_LIST_CODE:
  975.             pv->data.uint8 = *(PIL_UINT8 PTRTYPE *) data;
  976.             break;
  977.             
  978.         case PIL_UINT16_CODE:
  979.         case PIL_UINT16_LIST_CODE:
  980.             pv->data.uint16 = *(PIL_UINT16 PTRTYPE *) data;
  981.             break;
  982.             
  983.         case PIL_UINT32_CODE:
  984.         case PIL_UINT32_LIST_CODE:
  985.             pv->data.uint32 = *(PIL_UINT32 PTRTYPE *) data;
  986.             break;
  987.             
  988.         case PIL_DOUBLE_CODE:
  989.         case PIL_DOUBLE_LIST_CODE:
  990.             pv->data.dbl = *(PIL_DOUBLE PTRTYPE *) data;
  991.             break;
  992.             
  993.         case PIL_STRING_CODE:
  994.         case PIL_STRING_LIST_CODE:
  995.             if (pil_append_string(data, &pv->data.string)
  996.                 != PIL_OK) return (pil_last_error());
  997.             break;
  998.             
  999.         default:
  1000.             return (pil_set_error(PIL_BAD_VALUE_TYPE));
  1001.     }
  1002.     return (PIL_OK);
  1003. }
  1004.  
  1005.  
  1006. /*-----------------------------------------------------------------------*\
  1007.   pil_create_objid
  1008.  
  1009.     Creates a pil_object_id_list in the pil buffer at the next 
  1010.     available location. 
  1011.  
  1012.     Entry:    Pointer to a pil_object_id_list *
  1013.             char *    pointer to name of the pil_object_id_list
  1014.  
  1015.     Exit:    *aptrptr points to new pil_object_id_list. 
  1016.             Error code is returned.
  1017. \*-----------------------------------------------------------------------*/
  1018.  
  1019. PIL_ERROR pil_create_objid (aptrptr, name)
  1020. pil_object_id_list PTRPTR aptrptr;
  1021. char PTRTYPE *name;
  1022. {
  1023.     if (pil_alloc ((PIL_UINT32) sizeof(pil_object_id_list),
  1024.         (PIL_VOID PTRPTR) aptrptr) != PIL_OK) 
  1025.         return (pil_last_error());
  1026.  
  1027.  
  1028.     (*aptrptr)->next = NULL;
  1029.     if (pil_append_string(name, &(*aptrptr)->id) != PIL_OK) 
  1030.         return (pil_last_error());
  1031.     return (PIL_OK);
  1032. }
  1033.  
  1034.  
  1035. /*-----------------------------------------------------------------------*\
  1036.   pil_create_polypt
  1037.  
  1038.     Creates a pil_poly_pt in the pil buffer at the next 
  1039.     available location. 
  1040.  
  1041.     Entry:    Pointer to a pil_poly_pt *
  1042.             PIL_INT32    x value
  1043.             PIL_INT32     y value
  1044.  
  1045.     Exit:    *aptrptr points to new pil_poly_pt. 
  1046.             Error code is returned.
  1047. \*-----------------------------------------------------------------------*/
  1048.  
  1049. PIL_ERROR pil_create_polypt (aptrptr, x, y)
  1050. pil_poly_pt PTRPTR aptrptr;
  1051. PIL_INT32    x,y;
  1052. {
  1053.     if (pil_alloc((PIL_UINT32)sizeof(pil_poly_pt),
  1054.         (PIL_VOID PTRPTR)aptrptr) != PIL_OK) 
  1055.         return (pil_last_error());
  1056.  
  1057.  
  1058.     (*aptrptr)->next = NULL;
  1059.     (*aptrptr)->p.x = x;
  1060.     (*aptrptr)->p.y = y;
  1061.     return (PIL_OK);
  1062. }
  1063.  
  1064.  
  1065. /*-----------------------------------------------------------------------*\
  1066.   pil_create_pathpt
  1067.  
  1068.     Creates a pil_path_pt in the pil buffer at the next available location. 
  1069.  
  1070.     Entry:    Pointer to a pil_path_pt *
  1071.             char    type of point
  1072.             PIL_INT32    x value for first point
  1073.             PIL_INT32     y value    for first point
  1074.             PIL_INT32    x value for second point (if any)
  1075.             PIL_INT32    y value for second point (if any)
  1076.             PIL_INT32    x value for third point (if any)
  1077.             PIL_INT32    y value for third point (if any)
  1078.             PIL_INT32    curve radius
  1079.  
  1080.     Exit:    *aptrptr points to new pil_poly_pt. 
  1081.             Error code is returned.
  1082. \*-----------------------------------------------------------------------*/
  1083.  
  1084. PIL_ERROR pil_create_pathpt (aptrptr, type, x1, y1, x2, y2, x3, y3, radius)
  1085. pil_path_pt PTRPTR     aptrptr;
  1086. PIL_PATH_PART        type;
  1087. PIL_INT32            x1, y1;
  1088. PIL_INT32            x2, y2;
  1089. PIL_INT32            x3, y3;
  1090. PIL_INT32            radius;
  1091. {
  1092.     FAST pil_path_pt PTRTYPE *p;
  1093.     if (pil_alloc((PIL_UINT32)sizeof(pil_path_pt),
  1094.         (PIL_VOID PTRPTR)aptrptr) != PIL_OK) 
  1095.         return (pil_last_error());
  1096.         
  1097.  
  1098.     p = *aptrptr;
  1099.     p->type = type;
  1100.     p->next = NULL;
  1101.     
  1102.     
  1103.     switch (type) 
  1104.     {
  1105.         case PIL_MOVE_TO:
  1106.             p->p.mt.pt.x = x1;
  1107.             p->p.mt.pt.y = y1;
  1108.             break;
  1109.             
  1110.         case PIL_LINE_TO:
  1111.             p->p.lt.pt.x = x1;
  1112.             p->p.lt.pt.y = y1;
  1113.             break;
  1114.             
  1115.         case PIL_CURVE_TO:
  1116.             p->p.ct.ctrl_pt_1.x = x1;
  1117.             p->p.ct.ctrl_pt_1.y = y1;
  1118.             p->p.ct.ctrl_pt_2.x = x2;
  1119.             p->p.ct.ctrl_pt_2.y = y2;
  1120.             p->p.ct.end_pt.x = x3;
  1121.             p->p.ct.end_pt.y = y3;
  1122.             break;
  1123.             
  1124.         case PIL_ARC_TO:
  1125.             p->p.at.ctrl_pt_1.x = x1;
  1126.             p->p.at.ctrl_pt_1.y = y1;
  1127.             p->p.at.ctrl_pt_2.x = x2;
  1128.             p->p.at.ctrl_pt_2.y = y2;
  1129.             p->p.at.radius = radius;
  1130.             break;
  1131.     }
  1132.     return (PIL_OK);
  1133. }
  1134.  
  1135.  
  1136. /*-----------------------------------------------------------------------*\
  1137.   pil_create_object
  1138.  
  1139.     Subroutine for pil_create_component.
  1140.     Creates a pil_object in the pil buffer.
  1141.     The pil_object is put in the buffer at the next available location,
  1142.     and is initialized to the defaults as defined in the language spec.    
  1143.  
  1144.     Entry:    Pointer to a pil_object *
  1145.  
  1146.     Exit:    *optrptr points to new pil_object. Error code is returned.
  1147. \*-----------------------------------------------------------------------*/
  1148.  
  1149. PIL_ERROR pil_create_object(optrptr)
  1150. pil_object PTRPTR optrptr;
  1151. {
  1152.     FAST pil_object PTRTYPE    *optr;
  1153.     if (pil_alloc ((PIL_UINT32) sizeof(pil_object), 
  1154.         (PIL_VOID PTRPTR) optrptr) != PIL_OK) 
  1155.         return (pil_last_error());
  1156.  
  1157.  
  1158.     optr = *optrptr;
  1159.     pil_clear ((char PTRTYPE *)optr, (PIL_UINT32) sizeof(pil_object));
  1160.     optr->type = PIL_OBJECT_C;
  1161.     
  1162.     
  1163.     optr->units                 = PIL_DFT_OBJ_UNITS;
  1164.     optr->rotation_angle         = PIL_DFT_OBJ_ROTANG;
  1165.     optr->rotation_point.x         = PIL_DFT_OBJ_ROTPT_X;
  1166.     optr->rotation_point.y         = PIL_DFT_OBJ_ROTPT_Y;
  1167.     optr->clipshape.type         = PIL_DFT_OBJ_CLIPPER;
  1168.     optr->container.type         = PIL_DFT_OBJ_CONTAINER;
  1169.     optr->src_rect.ul.x         = PIL_DFT_OBJ_SRCRECT_X;
  1170.     optr->src_rect.ul.y         = PIL_DFT_OBJ_SRCRECT_Y;
  1171.     optr->src_rect.width         = PIL_DFT_OBJ_SRCRECT_W;
  1172.     optr->src_rect.height         = PIL_DFT_OBJ_SRCRECT_H;
  1173.     optr->rctype                 = PIL_DFT_OBJ_RCTYPE;
  1174.     optr->objtype                = PIL_DFT_OBJ_TYPE;
  1175.     optr->graphic.shape.type     = PIL_DFT_OBJ_GRAPHIC;
  1176.     optr->graphic.fill_rule     = PIL_DFT_FILL_RULE;
  1177.     optr->graphic.linecap         = PIL_DFT_LINE_CAP;
  1178.     optr->graphic.linejoin         = PIL_DFT_LINE_JOIN;
  1179.     optr->graphic.lineposition    = PIL_DFT_LINE_POSITION;
  1180.     optr->graphic.linewidth     = PIL_DFT_LINE_WIDTH;
  1181.     optr->graphic.miter_limit     = PIL_DFT_MITER_LIMIT;
  1182.     return (PIL_OK);
  1183. }
  1184.  
  1185.  
  1186. /*-----------------------------------------------------------------------*\
  1187.   pil_create_text_flow
  1188.  
  1189.     Subroutine for pil_create_component.
  1190.     Creates a pil_text_flow in the pil buffer.
  1191.     The pil_text_flow is put in the buffer at the next available loc,
  1192.     and is initialized to the defaults as defined in the language spec.    
  1193.  
  1194.     Entry:    Pointer to a pil_text_flow *
  1195.  
  1196.     Exit:    *nptrptr points to new pil_text_flow. Error code is returned.
  1197. \*-----------------------------------------------------------------------*/
  1198.  
  1199. PIL_ERROR pil_create_text_flow(tfptrptr)
  1200. pil_text_flow    PTRPTR tfptrptr;
  1201. {
  1202.     if (pil_alloc ((PIL_UINT32) sizeof(pil_text_flow), 
  1203.         (PIL_VOID PTRPTR) tfptrptr) != PIL_OK) 
  1204.         return (pil_last_error());
  1205.  
  1206.  
  1207.     pil_clear ((char PTRTYPE *) *tfptrptr, (PIL_UINT32) sizeof(pil_text_flow));
  1208.     (*tfptrptr)->type = PIL_TEXT_FLOW_C;
  1209.     return (PIL_OK);
  1210. }
  1211.  
  1212.  
  1213. /*-----------------------------------------------------------------------*\
  1214.   pil_create_group
  1215.  
  1216.     Subroutine for pil_create_component.
  1217.     Creates a pil_group in the pil buffer.
  1218.     The pil_group is put in the buffer at the next available loc,
  1219.     and is initialized to the defaults as defined in the language spec.    
  1220.  
  1221.     Entry:    Pointer to a pil_group *
  1222.  
  1223.     Exit:    *nptrptr points to new pil_group. Error code is returned.
  1224. \*-----------------------------------------------------------------------*/
  1225.  
  1226. PIL_ERROR pil_create_group (gptrptr)
  1227. pil_group PTRPTR gptrptr;
  1228. {
  1229.     if (pil_alloc ((PIL_UINT32) sizeof(pil_group), 
  1230.         (PIL_VOID PTRPTR) gptrptr) != PIL_OK) 
  1231.         return (pil_last_error());
  1232.  
  1233.  
  1234.     pil_clear ((char PTRTYPE *) *gptrptr, (PIL_UINT32) sizeof(pil_group));
  1235.     (*gptrptr)->type = PIL_GROUP_C;
  1236.     return (PIL_OK);
  1237. }
  1238.  
  1239.  
  1240. /*-----------------------------------------------------------------------*\
  1241.   pil_create_layout_start
  1242.  
  1243.     Subroutine for pil_create_component.
  1244.     Creates a pil_layout_start in the pil buffer.
  1245.     The pil_layout_start is put in the buffer at the next available loc,
  1246.     and is initialized to the defaults as defined in the language spec.    
  1247.  
  1248.     Entry:    Pointer to a pil_layout_start *
  1249.  
  1250.     Exit:    *lsptrptr points to new pil_layout_start, Err code is returned
  1251. \*-----------------------------------------------------------------------*/
  1252.  
  1253. PIL_ERROR pil_create_layout_start (lsptrptr)
  1254. pil_layout_start PTRPTR lsptrptr;
  1255. {
  1256.     if (pil_alloc ((PIL_UINT32) sizeof (pil_layout_start),
  1257.         (PIL_VOID PTRPTR) lsptrptr) != PIL_OK)
  1258.         return (pil_last_error());
  1259.  
  1260.  
  1261.     pil_clear ((char PTRTYPE *) *lsptrptr, (PIL_UINT32) sizeof(pil_layout_start));
  1262.     (*lsptrptr)->type = PIL_LAYOUT_START_C;
  1263.     return (pil_append_string (pil_version, &(*lsptrptr)->version));
  1264. }
  1265.  
  1266.  
  1267. /*-----------------------------------------------------------------------*\
  1268.   pil_create_layout_end
  1269.  
  1270.     Subroutine for pil_create_component.
  1271.     Creates a pil_layout_end in the pil buffer.
  1272.     The pil_layout_end is put in the buffer at the next available loc,
  1273.     and is initialized to the defaults as defined in the language spec.    
  1274.  
  1275.     Entry:    Pointer to a pil_layout_end *
  1276.  
  1277.     Exit:    *leptrptr points to new pil_layout_end. Error code is returned.
  1278. \*-----------------------------------------------------------------------*/
  1279.  
  1280. PIL_ERROR pil_create_layout_end (leptrptr)
  1281. pil_layout_end PTRPTR leptrptr;
  1282. {
  1283.     if (pil_alloc ((PIL_UINT32) sizeof (pil_layout_end),
  1284.         (PIL_VOID PTRPTR) leptrptr) != PIL_OK) 
  1285.         return (pil_last_error());
  1286.     (*leptrptr)->type = PIL_LAYOUT_END_C;
  1287.     return (PIL_OK);
  1288. }
  1289.  
  1290.  
  1291. /*-----------------------------------------------------------------------*\
  1292.   pil_create_content_start
  1293.  
  1294.     Subroutine for pil_create_component.
  1295.     Creates a pil_content_start in the pil buffer.
  1296.     The pil_content_start is put in the buffer at the next available loc,
  1297.     and is initialized to the defaults as defined in the language spec.    
  1298.  
  1299.     Entry:    Pointer to a pil_content_start *
  1300.  
  1301.     Exit:    *csptrptr points to new pil_content_start, Err code returned.
  1302. \*-----------------------------------------------------------------------*/
  1303.  
  1304. PIL_ERROR pil_create_content_start (csptrptr)
  1305. pil_content_start PTRPTR csptrptr;
  1306. {
  1307.     if (pil_alloc ((PIL_UINT32) sizeof (pil_content_start),
  1308.         (PIL_VOID PTRPTR) csptrptr) != PIL_OK)
  1309.         return (pil_last_error());
  1310.  
  1311.  
  1312.     pil_clear ((char PTRTYPE *) *csptrptr, (PIL_UINT32) sizeof(pil_content_start));
  1313.     (*csptrptr)->type = PIL_CONTENT_START_C;
  1314.     return (pil_append_string (pil_version, &(*csptrptr)->version));
  1315. }
  1316.  
  1317.  
  1318. /*-----------------------------------------------------------------------*\
  1319.   pil_create_content_hdr
  1320.  
  1321.     Subroutine for pil_create_component.
  1322.     Creates a pil_create_content_hdr in the pil buffer.
  1323.     The pil_create_content_hdr is put in the buffer at the next available 
  1324.     location and is cleared. The application must fill in all the values,
  1325.     as all are required and there are no defaults.
  1326.  
  1327.     Entry:    chptrpptr - Pointer to a pil_content_hdr *
  1328.  
  1329.     Exit:    *chptrptr points to new pil_content_hdr, Err code returned.
  1330. \*-----------------------------------------------------------------------*/
  1331.  
  1332. PIL_ERROR pil_create_content_hdr (chptrptr)
  1333. pil_content_hdr    PTRPTR chptrptr;
  1334. {
  1335.     if (pil_alloc ((PIL_UINT32) sizeof(pil_content_hdr),
  1336.         (PIL_VOID PTRPTR) chptrptr) != PIL_OK)
  1337.         return (pil_last_error());
  1338.  
  1339.  
  1340.     pil_clear ((char PTRTYPE *) *chptrptr, (PIL_UINT32) sizeof(pil_content_hdr));
  1341.     (*chptrptr)->type = PIL_CONTENT_HDR_C;
  1342.     return (PIL_OK);
  1343. }
  1344.  
  1345.  
  1346. /*-----------------------------------------------------------------------*\
  1347.   pil_create_content_data
  1348.  
  1349.     Subroutine for pil_create_component.
  1350.     Creates a pil_content_data compontent in the pil buffer.
  1351.     The pil_content_data is put in the buffer at the next available loc,
  1352.     and is initialized to the defaults as defined in the language spec.    
  1353.     (The default is no data (zero length, NULL pointer).
  1354.     The application can initialize the length and the pointer to the data.
  1355.  
  1356.     Entry:    Pointer to a pil_content_data *
  1357.  
  1358.     Exit:    *cdptrptr points to new pil_content_data component
  1359.             Err code returned.
  1360. \*-----------------------------------------------------------------------*/
  1361.  
  1362. PIL_ERROR pil_create_content_data (cdptrptr)
  1363. pil_content_data PTRPTR cdptrptr;
  1364. {
  1365.     if (pil_alloc ((PIL_UINT32) sizeof(pil_content_data),
  1366.         (PIL_VOID PTRPTR) cdptrptr) != PIL_OK)
  1367.         return (pil_last_error());
  1368.  
  1369.  
  1370.     pil_clear ((char PTRTYPE *) *cdptrptr, (PIL_UINT32) sizeof(pil_content_data));
  1371.     (*cdptrptr)->type = PIL_CONTENT_DATA_C;
  1372.     return (PIL_OK);
  1373. }
  1374.  
  1375. /*-----------------------------------------------------------------------*\
  1376.   pil_create_content_end
  1377.  
  1378.     Subroutine for pil_create_component.
  1379.     Creates a pil_content_end in the pil buffer.
  1380.     The pil_content_end is put in the buffer at the next available loc.    
  1381.  
  1382.     Entry:    Pointer to a pil_content_end * 
  1383.  
  1384.     Exit:    *ceptrptr points to new pil_content_end. Error code is returned.
  1385. \*-----------------------------------------------------------------------*/
  1386.  
  1387. PIL_ERROR pil_create_content_end (ceptrptr)
  1388. pil_content_end    PTRPTR ceptrptr;
  1389. {
  1390.     if (pil_alloc ((PIL_UINT32) sizeof(pil_content_end),
  1391.         (PIL_VOID PTRPTR) ceptrptr) != PIL_OK)
  1392.         return (pil_last_error());
  1393.     (*ceptrptr)->type = PIL_CONTENT_END_C;
  1394.     return (PIL_OK);
  1395. }
  1396.  
  1397.  
  1398. /* ------------------------------------------------------------------------    */
  1399. /*        U T I L I T Y  F U N C T I O N S                                    */
  1400. /* ------------------------------------------------------------------------    */
  1401. /*            pil_clear                                                        */
  1402. /*            pil_set_error                                                    */
  1403. /*            pil_append_string                                                */
  1404. /* ------------------------------------------------------------------------    */
  1405.  
  1406.  
  1407. /*-----------------------------------------------------------------------*\
  1408.   pil_clear
  1409.  
  1410.     Zero out a block of memory. This is provided because we don't want to
  1411.     assume the existence of ansi library routines such as memset(). However
  1412.     it may be wise to replace this call with whatever fast routine is 
  1413.     available on your platform to zero memory.    
  1414.  
  1415.     Entry:    Pointer to block of data, size in bytes
  1416.  
  1417.     Exit:    Writes zeros to the block.
  1418. \*-----------------------------------------------------------------------*/
  1419.  
  1420. PIL_VOID pil_clear (ptr, size)
  1421. FAST char PTRTYPE *ptr;
  1422. FAST PIL_UINT32 size;
  1423. {
  1424.     while (size--) *ptr++ = '\0';
  1425. }
  1426.  
  1427.  
  1428. /*-----------------------------------------------------------------------*\
  1429.   pil_set_error
  1430.  
  1431.     Sets the PIL_ERROR and returns the value set.
  1432.  
  1433.     Entry: PIL_ERROR
  1434.  
  1435.     Exit:  value  of pil error word
  1436. \*-----------------------------------------------------------------------*/
  1437.  
  1438. PIL_ERROR pil_set_error (new_err)
  1439. PIL_ERROR new_err;
  1440. {
  1441.     return (pil_error_val = new_err);
  1442. }
  1443.  
  1444.  
  1445. /*-----------------------------------------------------------------------*\
  1446.   pil_append_string
  1447.  
  1448.     Low-level routine that copies a string into the pil buffer.
  1449.     Calls pil_alloc. See warning on pil_alloc.
  1450.  
  1451.     Entry:    Pointer to null-terminated (C-language style) string
  1452.             Pointer to a pointer in which to return new string address
  1453.  
  1454.     Exit:    Returns PIL_OK on success, PIL_OUT_OF_MEMORY on failure.
  1455.             Pointer to new string (in the buffer) is set if successful
  1456.             NULL if failure, and pil_error_val will be set.
  1457. \*-----------------------------------------------------------------------*/
  1458.  
  1459. PIL_ERROR pil_append_string (str, aptrptr)
  1460. char PTRTYPE *str;
  1461. char PTRPTR aptrptr;
  1462. {
  1463.     if (str == NULL) 
  1464.     {
  1465.         *aptrptr = NULL;
  1466.         return (PIL_OK);
  1467.     }
  1468.     else if (pil_alloc ((PIL_UINT32) pil_strlen (str) + 1, 
  1469.     (PIL_VOID PTRPTR) aptrptr) == PIL_OK) 
  1470.     {
  1471.         pil_strcpy (*aptrptr, str);
  1472.         return (PIL_OK);
  1473.     }
  1474.     else return (pil_last_error());
  1475. }
  1476.  
  1477.  
  1478. /* ------------------------------------------------------------------------    */
  1479. /*        C  L I B R A R Y  F U N C T I O N S                                    */
  1480. /* ------------------------------------------------------------------------    */
  1481. /*            pil_atof                                                        */
  1482. /*            pil_strcmp                                                        */
  1483. /*            pil_strcpy                                                        */
  1484. /*            pil_strlen                                                        */
  1485. /* ------------------------------------------------------------------------    */
  1486.  
  1487.  
  1488. PIL_DOUBLE pil_atof (ascii_num)
  1489. char PTRTYPE *ascii_num;
  1490. {
  1491. #ifdef THINK_DA
  1492.     PIL_UINT8    token [PIL_MAX_TOKEN_SIZE];
  1493.     PIL_UINT8    len;
  1494.     /* create a Pascal string for str2num */
  1495.     for (len = 1; (token[len] = *ascii_num) != '\0'; len++, ascii_num++) {}
  1496.     token[0] = len-1;
  1497.     return(str2num(token));
  1498. #else
  1499. #ifdef WINDOWS3
  1500.     /* stdlib routines require near pointers, so copy string to a local buf */
  1501.     PIL_UINT8    token [PIL_MAX_TOKEN_SIZE];
  1502.     pil_strcpy(token,ascii_num);
  1503.     return (atof (token));
  1504. #else
  1505.     return (atof (ascii_num));
  1506. #endif
  1507. #endif
  1508. }
  1509.  
  1510.  
  1511. PIL_INT16 pil_strcmp (s1, s2)
  1512. FAST char PTRTYPE *s1;
  1513. FAST char PTRTYPE *s2;
  1514. {
  1515.     while (*s1 == *s2++) if (*s1++ == '\0') return (0);
  1516.     return ((PIL_INT16) (*s1 - *--s2));
  1517. }
  1518.  
  1519.  
  1520. char PTRTYPE *pil_strcpy (dst, src)
  1521. FAST char PTRTYPE *dst;
  1522. FAST char PTRTYPE *src;
  1523. {
  1524.     FAST char PTRTYPE *outp;
  1525.     outp = dst;
  1526.     while (*dst++ = *src++) ;
  1527.     return (outp);
  1528. }
  1529.  
  1530.  
  1531. PIL_UINT32 pil_strlen (s)
  1532. FAST char PTRTYPE *s;
  1533. {
  1534.     FAST PIL_UINT32 n;
  1535.     n = 0;
  1536.     while (*s++) n++;
  1537.     return (n);
  1538. }
  1539.  
  1540.  
  1541. /* ------------------------------------------------------------------------    */
  1542. /*        K E Y W O R D  T A B L E  F U N C T I O N S                            */
  1543. /* ------------------------------------------------------------------------    */
  1544. /*            pil_init_keywords                                                */
  1545. /* ------------------------------------------------------------------------    */
  1546.  
  1547.  
  1548. /*-----------------------------------------------------------------------*\
  1549.   pil_init_keywords
  1550.   
  1551.     Subroutine for pil_pg_init. Initialize table of keyword strings used
  1552.     by the generator and parser.
  1553.  
  1554.     Entry:    none 
  1555.  
  1556.     Exit:    pil_kws array is initialized
  1557.  
  1558. \*-----------------------------------------------------------------------*/
  1559.  
  1560. PIL_VOID pil_init_keywords()
  1561. {
  1562.     pil_kws[PIL_KW_OBJECT]                =    "object";
  1563.     pil_kws[PIL_KW_TEXT_FLOW]            =    "text-flow";
  1564.     pil_kws[PIL_KW_GROUP]                =    "group";
  1565.     pil_kws[PIL_KW_UNKNOWN]                =    "unknown";
  1566.     pil_kws[PIL_KW_ASCII_TEXT]            =    "ascii-text";
  1567.     pil_kws[PIL_KW_ATEX_ARIS]            =    "atex-aris";
  1568.     pil_kws[PIL_KW_ATEX_ITF]            =    "atex-itf";
  1569.     pil_kws[PIL_KW_EPS]                    =    "eps";
  1570.     pil_kws[PIL_KW_ICL]                    =    "icl";
  1571.     pil_kws[PIL_KW_IT8_1]                =    "it8.1";
  1572.     pil_kws[PIL_KW_IT8_2]                =    "it8.2";
  1573.     pil_kws[PIL_KW_MS_RTF]                =    "microsoft-rtf";
  1574.     pil_kws[PIL_KW_MS_WORD_3]            =    "microsoft-word-3.0";
  1575.     pil_kws[PIL_KW_MS_WORD_4]            =    "microsoft-word-4.0";
  1576.     pil_kws[PIL_KW_MIF]                    =    "mif";
  1577.     pil_kws[PIL_KW_PICT]                =    "pict";
  1578.     pil_kws[PIL_KW_PIL_LAYOUT_NTET]        =    "pil-layout";
  1579.     pil_kws[PIL_KW_POSTSCRIPT]            =    "postscript";
  1580.     pil_kws[PIL_KW_QUARK_XPRESSTAGS]    =    "quark-xpresstags";
  1581.     pil_kws[PIL_KW_SCITEX_CT]            =    "scitex-ct";
  1582.     pil_kws[PIL_KW_SCITEX_HANDSHAKE]    =    "scitex-handshake";
  1583.     pil_kws[PIL_KW_SCITEX_LW]            =    "scitex-lw";
  1584.     pil_kws[PIL_KW_SGML]                =    "sgml";
  1585.     pil_kws[PIL_KW_TIFF]                =    "tiff";
  1586.     pil_kws[PIL_KW_WP_100]                =    "word-perfect-1.0";
  1587.     pil_kws[PIL_KW_WP_102]                =    "word-perfect-1.02";
  1588.     pil_kws[PIL_KW_XYQUEST_XYWRITE]        =    "xyquest-xywrite";
  1589.     pil_kws[PIL_KW_MAC_FILENAME]        =    "mac-filename";
  1590.     pil_kws[PIL_KW_UNIX_FILENAME]        =    "unix-filename";
  1591.     pil_kws[PIL_KW_MSDOS_FILENAME]        =    "ms-dos-filename";
  1592.     pil_kws[PIL_KW_OS2_FILENAME]        =    "os2-filename";
  1593.     pil_kws[PIL_KW_VMS_FILENAME]        =    "vms-filename";
  1594.     pil_kws[PIL_KW_VM_FILENAME]            =    "vm-filename";
  1595.     pil_kws[PIL_KW_LCD_FILENAME]        =    "lcd-filename";
  1596.     pil_kws[PIL_KW_INLINE]                =    "inline";
  1597.     pil_kws[PIL_KW_NAME_TABLE]            =    "name-table";
  1598.     pil_kws[PIL_KW_CANVAS]                =    "canvas";
  1599.     pil_kws[PIL_KW_DIMENSIONS]            =    "dimensions";    
  1600.     pil_kws[PIL_KW_UNITS]                =    "units";
  1601.     pil_kws[PIL_KW_USER_NAME]            =    "user-name";
  1602.     pil_kws[PIL_KW_TYPE]                =    "type";
  1603.     pil_kws[PIL_KW_CLIPPER]                =    "clipper";
  1604.     pil_kws[PIL_KW_APPLICATION]            =    "application";
  1605.     pil_kws[PIL_KW_APP_NAME]            =    "app-name";
  1606.     pil_kws[PIL_KW_APP_INT8]            =    "int8";        
  1607.     pil_kws[PIL_KW_APP_INT16]            =    "int16";
  1608.     pil_kws[PIL_KW_APP_INT32]            =    "int32";
  1609.     pil_kws[PIL_KW_APP_UINT8]            =    "uint8";
  1610.     pil_kws[PIL_KW_APP_UINT16]            =    "uint16";
  1611.     pil_kws[PIL_KW_APP_UINT32]            =    "uint32";
  1612.     pil_kws[PIL_KW_APP_DOUBLE]            =    "double";
  1613.     pil_kws[PIL_KW_APP_STRING]            =    "string";
  1614.     pil_kws[PIL_KW_FILL_RULE]            =    "fill-rule";
  1615.     pil_kws[PIL_KW_RECTANGLE]            =    "rectangle";
  1616.     pil_kws[PIL_KW_CIRCLE]                =    "circle";
  1617.     pil_kws[PIL_KW_ELLIPSE]                =    "ellipse";
  1618.     pil_kws[PIL_KW_POLYGON]                =    "polygon";
  1619.     pil_kws[PIL_KW_CLOSED_PATH]            =    "closed-path";
  1620.     pil_kws[PIL_KW_EVEN_ODD]            =    "even-odd";
  1621.     pil_kws[PIL_KW_NZ_WINDING]            =    "non-zero-winding";
  1622.     pil_kws[PIL_KW_MOVE_TO]                =    "move-to";
  1623.     pil_kws[PIL_KW_LINE_TO]                =    "line-to";
  1624.     pil_kws[PIL_KW_CURVE_TO]            =    "curve-to";
  1625.     pil_kws[PIL_KW_ARC_TO]                =    "arc-to";
  1626.     pil_kws[PIL_KW_FLOW_LABEL]            =    "flow-label";
  1627.     pil_kws[PIL_KW_FLOW_OBJECTS]        =    "objects";
  1628.     pil_kws[PIL_KW_FLOW_FROM]            =    "from";
  1629.     pil_kws[PIL_KW_FLOW_TO]                =    "to";
  1630.     pil_kws[PIL_KW_FLOW_CONTENT]        =    "content";
  1631.     pil_kws[PIL_KW_ID]                    =    "id";
  1632.     pil_kws[PIL_KW_GROUP_OBJECTS]        =    "objects";
  1633.     pil_kws[PIL_KW_ORIGIN]                =    "origin";
  1634.     pil_kws[PIL_KW_ROT_ANGLE]            =    "rot-angle";
  1635.     pil_kws[PIL_KW_ROT_POINT]            =    "rot-point";
  1636.     pil_kws[PIL_KW_CONTAINER]            =    "container";
  1637.     pil_kws[PIL_KW_GRAPHIC]                =    "graphic";
  1638.     pil_kws[PIL_KW_RC_TYPE]                =    "rc-type";
  1639.     pil_kws[PIL_KW_RC_NAME]                =    "rc-name";
  1640.     pil_kws[PIL_KW_BBOX]                =    "bbox";
  1641.     pil_kws[PIL_KW_RC_TYPE_TEXT]        =    "text";    
  1642.     pil_kws[PIL_KW_RC_TYPE_GEOMETRY]    =    "geometry";
  1643.     pil_kws[PIL_KW_RC_TYPE_LINEART]        =    "lineart";
  1644.     pil_kws[PIL_KW_RC_TYPE_IMAGE]        =    "image";
  1645.     pil_kws[PIL_KW_COLOR_MODEL]            =    "color-model";
  1646.     pil_kws[PIL_KW_DEV_GRAY]            =    "device-gray";
  1647.     pil_kws[PIL_KW_CAL_GRAY]            =    "calibrated-gray";
  1648.     pil_kws[PIL_KW_DEV_RGB]                =    "device-rgb";
  1649.     pil_kws[PIL_KW_CAL_RGB]                =    "calibrated-rgb";
  1650.     pil_kws[PIL_KW_DEV_CMYK]            =    "device-cmyk";
  1651.     pil_kws[PIL_KW_SPOT]                =    "spot";
  1652.     pil_kws[PIL_KW_PANTONE]                =    "pantone";
  1653.     pil_kws[PIL_KW_RENDER_OP]            =    "render-op";
  1654.     pil_kws[PIL_KW_STROKE]                =    "stroke";
  1655.     pil_kws[PIL_KW_FILL]                =    "fill";
  1656.     pil_kws[PIL_KW_FILL_STROKE]            =    "fill-and-stroke";
  1657.     pil_kws[PIL_KW_RENDER_ATTR]            =    "render-attributes";
  1658.     pil_kws[PIL_KW_STROKE_COLOR]        =    "stroke-color";
  1659.     pil_kws[PIL_KW_POSITION]            =    "position";
  1660.     pil_kws[PIL_KW_WIDTH]                =    "width";
  1661.     pil_kws[PIL_KW_CAP]                    =    "cap";
  1662.     pil_kws[PIL_KW_JOIN]                =    "join";
  1663.     pil_kws[PIL_KW_MITER_LIMIT]            =    "miter-limit";
  1664.     pil_kws[PIL_KW_FILL_COLOR]            =    "fill-color";
  1665.     pil_kws[PIL_KW_INSIDE]                =    "inside";
  1666.     pil_kws[PIL_KW_OUTSIDE]                =    "outside";
  1667.     pil_kws[PIL_KW_CENTERED]            =    "centered";
  1668.     pil_kws[PIL_KW_BUTT_CAP]            =    "butt-cap";
  1669.     pil_kws[PIL_KW_ROUND_CAP]            =    "round-cap";
  1670.     pil_kws[PIL_KW_PROJECTING_CAP]        =    "projecting-cap";
  1671.     pil_kws[PIL_KW_MITER_JOIN]            =    "miter-join";
  1672.     pil_kws[PIL_KW_BEVEL_JOIN]            =    "bevel-join";
  1673.     pil_kws[PIL_KW_ROUND_JOIN]            =    "round-join";
  1674.     pil_kws[PIL_KW_LINE]                =    "line";
  1675.     pil_kws[PIL_KW_ARC]                    =    "arc";
  1676.     pil_kws[PIL_KW_BEZIER]                =    "bezier";
  1677.     pil_kws[PIL_KW_POLY_LINE]            =    "poly-line";
  1678.     pil_kws[PIL_KW_OPEN_PATH]            =    "open-path";
  1679.     pil_kws[PIL_KW_DATA]                =    "data";
  1680.     pil_kws[PIL_KW_HEADER]                =    "header";
  1681.     pil_kws[PIL_KW_LITTLE_ENDIAN]        =    "little-endian";
  1682.     pil_kws[PIL_KW_BIG_ENDIAN]            =    "big-endian";
  1683.     pil_kws[PIL_KW_ASCII]                =    "ascii";
  1684.     pil_kws[PIL_KW_BINARY]                =    "binary";
  1685.     pil_kws[PIL_KW_LAYOUT]                =    "pil-layout-";
  1686.     pil_kws[PIL_KW_CONTENT]                =    "pil-content-";
  1687.     pil_kws[PIL_KW_LAYOUT_VS1]            =    "pil-layout-5.0";
  1688.     pil_kws[PIL_KW_LAYOUT_VS2]            =    "pil-layout-5.00";
  1689.     pil_kws[PIL_KW_LAYOUT_VS3]            =    "pil-layout-05.0";
  1690.     pil_kws[PIL_KW_LAYOUT_VS4]            =    "pil-layout-05.00";
  1691.     pil_kws[PIL_KW_CONTENT_VS1]            =    "pil-content-5.0";
  1692.     pil_kws[PIL_KW_CONTENT_VS2]            =    "pil-content-5.00";
  1693.     pil_kws[PIL_KW_CONTENT_VS3]            =    "pil-content-05.0";
  1694.     pil_kws[PIL_KW_CONTENT_VS4]            =    "pil-content-05.00";
  1695.     pil_kws[PIL_KW_CLIPPER_SHAPE]        =    "clipper-shape";
  1696.     pil_kws[PIL_KW_CONTAINER_SHAPE]        =    "container-shape";
  1697.     pil_kws[PIL_KW_OBJ_TEXT]            =    "text";
  1698.     pil_kws[PIL_KW_OBJ_PICTURE]            =    "picture";
  1699.     pil_kws[PIL_KW_OBJ_PRIMITIVE]        =    "primitive";
  1700. }
  1701. /******************* End of pilapi.c *********************/
  1702.